/*
 * OREKIT-X
 * Copyright 2002-2008 CS Communication & Systemes
 * 
 * Parts of this software package have been licensed to CS
 * Communication & Systemes (CS) under one or more contributor license
 * agreements.  See the NOTICE file distributed with this work for
 * additional information.
 *  
 * This is an experimental copy of OREKIT from www.orekit.org.
 * Please use the original OREKIT from orekit.org for normal work
 * unrelated to this research project.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You
 * may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.  See the License for the specific language governing
 * permissions and limitations under the License.
 */
package ore.time;

/** 
 * Barycentric Dynamic Time.
 * 
 * Time used to account for time dilation when calculating the orbits
 * of planets, asteroids, comets and interplanetary spacecraft in the
 * Solar system.
 * 
 * It was based on a Dynamical time scale but was not well defined and
 * not rigorously correct as a relativistic time scale. It was
 * subsequently deprecated in favour of Barycentric Coordinate Time
 * (TCB), but at the 2006 General Assembly of the International
 * Astronomical Union TDB was rehabilitated by making it a specific
 * fixed linear transformation of TCB.
 * 
 * By convention, TDB = TT + 0.001658 sin(g) + 0.000014 sin(2g)seconds
 * where g = 357.53 + 0.9856003 (JD - 2451545) degrees.
 * 
 * @author Aude Privat
 */
public final class TDBScale 
    extends Object
    implements TimeScale
{

    public final static TimeScale Instance = new TDBScale();


    private TDBScale() {
        super();
    }


    public double offsetFromTAI(AbsoluteDate date) {
        double dtDays = date.durationFrom(AbsoluteDate.J2000_EPOCH) / 86400;
        double g = Math.toRadians(357.53 + 0.9856003 * dtDays);
        return TimeScalesFactory.getTT().offsetFromTAI(date) + (0.001658 * Math.sin(g) + 0.000014 * Math.sin(2 * g));
    }
    public double offsetToTAI(DateComponents date, TimeComponents time) {
        AbsoluteDate reference = new AbsoluteDate(date, time, TimeScalesFactory.getTAI());
        double offset = 0;
        for (int i = 0; i < 3; i++) {
            offset = -offsetFromTAI(new AbsoluteDate(reference, offset));
        }
        return offset;
    }
    public String getName() {
        return "TDB";
    }
    public String toString() {
        return this.getName();
    }
}
